/**
 * 重构
 * typescript 支持三种可以声明任意类型的变量，type，infer，类型参数，
 * 但三种方式都不能对原始类型进行修改，如果我们想修改原始类型，就需要重新构造，产生新的类型。
 */
type ArrayPush<T extends unknown[],Ele extends unknown> = [...T,Ele]
type TestPush = ArrayPush<[1,2],3> // [1, 2, 3]

type ArrayUnshift<T extends unknown[],Ele extends unknown> = [Ele,...T]
type TestUnshift = ArrayUnshift<[1,2],3>; // [3, 1, 2]

type GetUppercase<Str extends string> =
  Str extends `${infer Prefix}${infer Rest}`
  ? `${Uppercase<Prefix>}${Rest}` : never;
type GetUppercase1 = GetUppercase<'string'>

type CamelCase<Str extends string> =
  Str extends `${infer Left}_${infer Right}` ?
  `${Left}${GetUppercase<Right>}` : never;
type TestCamelCase = CamelCase<'test_came'>; // testCame

type DeleteStr<Str extends string,Target extends string> =
  Str extends `${infer Prefix}${Target}${infer Subfix}`
  ? `${Prefix}${Subfix}` : never;
type TestDelete = DeleteStr<'hello world',' world'>; // hello

type AddParameters<Fun extends (...args: any[]) => any,Arg> =
  Fun extends (...args: infer Args) => infer Return
  ? (...args: [...Args,Arg]) => Return : never;

type ChangeReturnType<Fun extends (...args: any[]) => any,TeturnType> =
  Fun extends (...args: infer Args) => infer Return
  ? (...args: Args) => TeturnType : never;